package org.xtext.example.mydsl.validation;

import java.util.HashMap;
import java.util.Map;
import org.eclipse.xtext.validation.Check;
import org.xtext.example.mydsl.myDsl.Abs;
import org.xtext.example.mydsl.myDsl.App;
import org.xtext.example.mydsl.myDsl.Dich;
import org.xtext.example.mydsl.myDsl.Prog;
import org.xtext.example.mydsl.myDsl.Tapp;
import org.xtext.example.mydsl.myDsl.Term;
import org.xtext.example.mydsl.myDsl.Uq;
import org.xtext.example.mydsl.myDsl.Var;
 


public class MyDslJavaValidator extends AbstractMyDslJavaValidator {


	
	
	
	
	@Check
	public void checkFreeVariable(Prog prog) {
		for(Dich t : prog.getD())
			checkFreeAux(t.getTerm(), new HashMap<String, String>());
		checkFreeAux(prog.getMain(), new HashMap<String, String>());
	}

	private void checkFreeAux(Term t, Map<String, String> varMap) {
		
		if(t instanceof Var){
			Var var = (Var)t;
			if(!varMap.containsKey(var.getName()))
				warning(var.getName()+"  should be bounded", null);
		
		}else if(t instanceof Abs){
			Abs abs =(Abs)t;
			varMap.put(abs.getParam(), abs.getParam());
			checkFreeAux(abs.getBody(), varMap);
			
		}else if(t instanceof App){
			App app = (App)t;
			checkFreeAux(app.getT1(), cloneMap(varMap));
			checkFreeAux(app.getT2(), cloneMap(varMap));
		}else if(t instanceof Uq){
			Uq uq = (Uq)t;
			checkFreeAux(uq.getTerm(), varMap);
		}else if(t instanceof Tapp){
			Tapp tapp = (Tapp)t;
			checkFreeAux(tapp.getTerm(), varMap);
		}	
	}
	
	public static Map<String, String>cloneMap(Map<String, String> map){
		Map<String, String> clone =  new HashMap<String, String>();
		for(String e : map.keySet()){
			clone.put(e, map.get(e));
		}
		return clone;
	}

}
